package core.util.bean;

import java.io.Serializable;
import java.util.Objects;

/**
 * Etherクラス
 * @author Tadashi Nakayama
 *
 * @param <L> 左要素ジェネリクス
 * @param <R> 右要素ジェネリクス
 */
public final class Either<L, R> implements Serializable {

	/** serialVersionUID */
	private static final long serialVersionUID = -7538827957919835232L;

	/** 左要素 */
	private final L left;
	/** 右要素 */
	private final R right;

	/**
	 * コンストラクタ
	 * @param l 左要素
	 * @param r 右要素
	 */
	private Either(final L l, final R r) {
		if (l == r) {
			throw new IllegalArgumentException();
		}

		this.left = l;
		this.right = r;
	}

	/**
	 * 左要素Either作成
	 * @param <L> 左要素ジェネリクス
	 * @param <R> 右要素ジェネリクス
	 * @param l 左要素
	 * @return 左要素Either
	 */
	public static <L, R> Either<L, R> left(final L l) {
		return new Either<>(l, null);
	}

	/**
	 * 左要素存在取得
	 * @return 左要素
	 */
	public L left() {
		return this.left;
	}

	/**
	 * 左要素存在確認
	 * @return 左要素が存在する場合 true を返す。
	 */
	public boolean isLeft() {
		return this.left != null;
	}

	/**
	 * 右要素取得
	 * @return 右要素
	 */
	public R right() {
		return this.right;
	}

	/**
	 * 右要素存在確認
	 * @return 右要素が存在する場合 true を返す。
	 */
	public boolean isRight() {
		return this.right != null;
	}

	/**
	 * 右要素Either作成
	 * @param <L> 左要素ジェネリクス
	 * @param <R> 右要素ジェネリクス
	 * @param r 右要素
	 * @return 右要素Either
	 */
	public static <L, R> Either<L, R> right(final R r) {
		return new Either<>(null, r);
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		if (this.left == null) {
			return Objects.toString(this.right, "");
		}
		return Objects.toString(this.left, "");
	}
}
